package com.jiashihui.schema_lgorithm.java.basics;

import java.math.BigDecimal;

/**
 // decimal
 // 构造器                   描述
 // BigDecimal(int)       创建一个具有参数所指定整数值的对象。
 // BigDecimal(double)    创建一个具有参数所指定双精度值的对象。
 // BigDecimal(long)      创建一个具有参数所指定长整数值的对象。
 // BigDecimal(String)    创建一个具有参数所指定以字符串表示的数值的对象。
 //        方法                    描述
 //        add(BigDecimal)       BigDecimal对象中的值相加，然后返回这个对象。
 //        subtract(BigDecimal)  BigDecimal对象中的值相减，然后返回这个对象。
 //        multiply(BigDecimal)  BigDecimal对象中的值相乘，然后返回这个对象。
 //        divide(BigDecimal)    BigDecimal对象中的值相除，然后返回这个对象。
 //        toString()            将BigDecimal对象的数值转换成字符串。
 //        doubleValue()         将BigDecimal对象中的值以双精度数返回。
 //        floatValue()          将BigDecimal对象中的值以单精度数返回。
 //        longValue()           将BigDecimal对象中的值以长整数返回。
 //        intValue()            将BigDecimal对象中的值以整数返回。
 */
public class BigDecimalTest {
    public static void main(String[] args) {
        System.out.println(0.05 + 0.01);
        System.out.println(1.0 - 0.42);
        System.out.println(4.015 * 100);
        System.out.println(123.3 / 100);

//        输出：
//        0.060000000000000005
//        0.5800000000000001
//        401.49999999999994
//        1.2329999999999999

        // Java中float的精度为6-7位有效数字。double的精度为15-16位。
        // float和double只能用来做科学计算和工程计算。商业运算中我们要使用BigDecimal。

        System.out.println("##############################################");

//        在使用BigDecimal时，使用它的BigDecimal(String)构造器创建对象才有意义。
//        其他的如BigDecimal b = new BigDecimal(1)这种，还是会发生精度丢失的问题。
        BigDecimal a = new BigDecimal(1.01);
        BigDecimal b = new BigDecimal(1.02);
        BigDecimal c = new BigDecimal("1.01");
        BigDecimal d = new BigDecimal("1.02");
        System.out.println(a.add(b));
        System.out.println(c.add(d));

//        输出：
//        2.0300000000000000266453525910037569701671600341796875
//        2.03

//        BigDecimal(String)构造器的变量在进行运算的时候却没有出现这种问题。
//        究其原因计算机组成原理里面都有，它们的编码决定了这样的结果。
//        long可以准确存储19位数字，而double只能准备存储16位数字。
//        double由于有exp位，可以存16位以上的数字，但是需要以低位的不精确作为代价。
//        如果需要高于19位数字的精确存储，则必须用BigInteger来保存，当然会牺牲一些性能。
//        所以我们一般使用BigDecimal来解决商业运算上丢失精度的问题的时候，
//        声明BigDecimal对象的时候一定要使用它构造参数为String的类型的构造器。


    }
}
